package com.yunshipei.core.model;

import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;

import com.yunshipei.core.common.ContentValues;
import com.yunshipei.core.manager.XCloud2Map;
import com.yunshipei.core.ui.TabItem;
import com.yunshipei.core.ui.view.FaceWebView;
import com.yunshipei.core.utils.CommonUtils;
import com.yunshipei.core.utils.YspLogUtils;

import org.json.JSONException;
import org.json.JSONObject;
import org.xwalk.core.XWalkView;

import java.util.List;
import java.util.Vector;

public class JavascriptInterfaceModel {
    private String mPcUrl = "";
    private Handler mHandler = new Handler();
    private boolean isDebug = false;
    private String mUrl = "";
    private XWalkView mWebView;
    private WebView mFaceView;
    private MatcherResult mMatcherResult;
    private boolean isSupport2WebView = false;
    private OnJavascriptInterfaceModelInteractionListener mJavascriptInterfaceModelInteractionListener;
    private List<String> mLogs;

    public JavascriptInterfaceModel(String homeUrl, XWalkView webView, MatcherResult matcherResult, boolean isDebug, OnJavascriptInterfaceModelInteractionListener onJavascriptInterfaceModelInteractionListener) {
        this.mUrl = CommonUtils.removeParams(homeUrl, new String[]{ContentValues.WEB_APP_ID, ContentValues.WEB_APP_NAME});
        this.mWebView = webView;
        this.isDebug = isDebug;
        this.mMatcherResult = matcherResult;
        this.mJavascriptInterfaceModelInteractionListener = onJavascriptInterfaceModelInteractionListener;
        mLogs = XCloud2Map.getInstance().getConfigInfo().getLogs();
    }

    /**
     * 关闭当前页面，对应window.close();
     * 多tab使用比较多，如果一个tab中有一个WebView则返回九宫格，如果有多个WebView，则关闭的当前WebView返回到上一个WebView
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void closeWindow() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mJavascriptInterfaceModelInteractionListener.closeWindow();
            }
        });
    }

    /**
     * 适配页面设置PC端URL，浏览器有打开电脑版功能
     *
     * @param url 适配应用返回的当前适配的PC版的URL
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void setTargetURL(String url) {
        this.mPcUrl = url;
    }

    /**
     * 返回方法，适配页面没有返回的history，返回时，客户端先调用适配页面的js方法返回，如果能返回则适配页面自己返回，如果适配页面
     * 返回到最顶层了，会调用这个方法，由原声页面自己处理返回。
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void back() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mJavascriptInterfaceModelInteractionListener.onBack();
            }
        });
    }

    /**
     * 运行时加载完毕调用，用于预加载
     */
    @Deprecated
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void loadFinished() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mJavascriptInterfaceModelInteractionListener.onLoadAdapter();
            }
        });
    }

    /**
     * 获取二级菜单列表，因为要控制二级菜单的权限，该内容由manager下发，如果加载的是enterplorer协议，则
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getMenu() {
        return mJavascriptInterfaceModelInteractionListener.getMenu();
    }

    //=================单点登录相关START===================

    /**
     * 获取用户名的XPath
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getUserElementXPath(String url) {
        url = CommonUtils.removeParams(url, new String[]{ContentValues.WEB_APP_NAME, ContentValues.WEB_APP_ID});
        String xPath = "null";
        AutoLoginModel autoLoginModel = mJavascriptInterfaceModelInteractionListener.getAutoLoginConfig(url);
        if (autoLoginModel != null) {
            String result = autoLoginModel.getUserNameXPath();
            if (!TextUtils.isEmpty(result)) {
                xPath = result;
            }
        }
        return xPath;
    }

    /**
     * 获取用密码的XPath
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getPassElementXPath(String url) {
        url = CommonUtils.removeParams(url, new String[]{ContentValues.WEB_APP_NAME, ContentValues.WEB_APP_ID});
        String xPath = "null";
        AutoLoginModel autoLoginModel = mJavascriptInterfaceModelInteractionListener.getAutoLoginConfig(url);
        if (autoLoginModel != null) {
            String result = autoLoginModel.getPasswordXPath();
            if (!TextUtils.isEmpty(result)) {
                xPath = result;
            }
        }
        return xPath;
    }

    /**
     * 获取验证码的XPath
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getCertElementXPath(String url) {
        return "null";
    }

    /**
     * 获取提交按钮的XPath
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getSubmitElementXPath(String url) {
        url = CommonUtils.removeParams(url, new String[]{ContentValues.WEB_APP_NAME, ContentValues.WEB_APP_ID});
        String xPath = "null";
        AutoLoginModel autoLoginModel = mJavascriptInterfaceModelInteractionListener.getAutoLoginConfig(url);
        if (autoLoginModel != null) {
            String result = autoLoginModel.getSubmitBtnXPath();
            if (!TextUtils.isEmpty(result)) {
                xPath = result;
            }
        }
        return xPath;
    }

    /**
     * 获取网站单点登录的用户名
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getUsername(String url) {
        url = CommonUtils.removeParams(url, new String[]{ContentValues.WEB_APP_NAME, ContentValues.WEB_APP_ID});
        long bel = System.currentTimeMillis() - mJavascriptInterfaceModelInteractionListener.getLastSSOTimeStamp();
        if (bel < 10 * 60 * 1000) {
            return "";
        }
        String userName = "";
        AutoLoginModel autoLoginModel = mJavascriptInterfaceModelInteractionListener.getAutoLoginConfig(url);
        if (autoLoginModel != null) {
            String result = autoLoginModel.getUserName();
            if (!TextUtils.isEmpty(result)) {
                userName = result;
            }
        }
        return userName;
    }

    /**
     * 获p取网站单点登录的密码
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getPassword(String url) {
        url = CommonUtils.removeParams(url, new String[]{ContentValues.WEB_APP_NAME, ContentValues.WEB_APP_ID});
        String password = "";
        AutoLoginModel autoLoginModel = mJavascriptInterfaceModelInteractionListener.getAutoLoginConfig(url);
        if (autoLoginModel != null) {
            String result = autoLoginModel.getPassword();
            if (!TextUtils.isEmpty(result)) {
                password = result;
                mJavascriptInterfaceModelInteractionListener.updateSSOTimeStamp(System.currentTimeMillis());
            }
        }
        return password;
    }
    //========================单点登录相关END====================

    /**
     * 保存适配页面错误日志
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void saveLog(String log) {
        try {
            JSONObject jsonObject = new JSONObject(log);
            String level = jsonObject.optString("level", "info");
            if (mLogs.contains(level)) {
                YspLogUtils.adapterLog(log);
            }
        } catch (JSONException ignored) {
        }
    }

    /**
     * 显示加载loading
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void showLoading(final String message) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mJavascriptInterfaceModelInteractionListener.showLoading(message);
            }
        });
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void showLoading() {
        showLoading("加载中，请稍候...");
    }

    /**
     * 关闭加载loading
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void hideLoading() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mJavascriptInterfaceModelInteractionListener.hideLoading();
            }
        });
    }

    /**
     * 应用版本
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getEnterplorerVersions() {
        return mJavascriptInterfaceModelInteractionListener.getAppVersion();
    }

    /**
     * 打开一个新窗口
     *
     * @param url url可能带参数，如果带有_ysp_forcepc则是pc版，否则还得走匹配逻辑，匹配成功打开新WebView加载适配
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void openWindow(final String url) {
        mJavascriptInterfaceModelInteractionListener.openWindow(url);
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public boolean isDebug() {
        return isDebug;
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getAdapterInfo() {
        String adapterInfo = "";
        if (mMatcherResult != null) {
            String adapter = mMatcherResult.getAdapter();
            if (!TextUtils.isEmpty(adapter)) {
                adapterInfo = mMatcherResult.getCloudAppModle().getManifestContent();
            }
        }
        return adapterInfo;
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void openDocument(final String data) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mJavascriptInterfaceModelInteractionListener.yspOpenDocFile(data);
            }
        });
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getModel() {
        String content = "";
        if (mMatcherResult != null) {
            String adapter = mMatcherResult.getAdapter();
            if (!TextUtils.isEmpty(adapter)) {
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("modelURL", "xcloud2json/" + adapter.replace("adapter://", ""));
                    jsonObject.put("targetURL", Uri.encode(mUrl));
                    jsonObject.put("hasAutoLogin", isEnableAutoLogin(mUrl));
                } catch (JSONException ignored) {
                }
            }
        }
        return content;
    }

    //适配获取是否支持密码代填功能
    public boolean isEnableAutoLogin(String url) {
        if (!TextUtils.isEmpty(url)) {
            url = CommonUtils.removeParams(url, new String[]{ContentValues.WEB_APP_ID, ContentValues.WEB_APP_NAME});
            long bel = System.currentTimeMillis() - mJavascriptInterfaceModelInteractionListener.getLastSSOTimeStamp();
            AutoLoginModel autoLoginModel = mJavascriptInterfaceModelInteractionListener.getAutoLoginConfig(url);
            return bel >= 10 * 60 * 1000 && autoLoginModel != null;
        }
        return false;
    }

    public void destroy() {
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
        }
        if (faceMessage != null) {
            faceMessage.clear();
        }
        if (backMessage != null) {
            backMessage.clear();
        }
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public boolean use2WebView() {
        return isSupport2WebView;
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void postMessage(String id, String message) {
        sendMessage(id, message);
    }

    /**
     * @param id      0代表后面runtimeEngineApp.html调用该方法
     * @param message 1代表app.html调用该方法
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void sendMessage(final String id, final String message) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (id.equals("0")) {
                    if (!isFaceReady) {
                        backMessage.add(message);
                        return;
                    }
                    mFaceView.loadUrl(generateJSOnMessageFunStr(id, message));
                } else {
                    if (!isBackReady) {
                        faceMessage.add(message);
                        return;
                    }
                    mWebView.loadUrl(generateJSOnMessageFunStr(id, message));
                }
            }
        });
    }

    /**
     * 发送事件到本地,适配页面需要向本地WebView发事件，比如刷新，重新加载某个页面，加载某个数据
     */
    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void postMessageToNative(final String event, final String data) {
        /**
         * android不需要实现该方法，如果适配需要直接和客户app交互，通过tabFragment的addJavascriptInterface方法即可实现交互
         *
         * 该方法是IOS的app需要和适配交互的时候调用的
         */
    }

    private boolean isFaceReady = false;
    private boolean isBackReady = false;
    private Vector<String> faceMessage = new Vector<>();   //app.html的WebView（原生WebView）发送过来的消息队列
    private Vector<String> backMessage = new Vector<>();   //runtimeEngineApp.html（Crosswalk WebView）发送过来的消息队列

    public void setReload(String refreshModel) {
        if (TabItem.YSP_REFRESH_MODEL_ALL.equals(refreshModel)) {
            isFaceReady = false;
            isBackReady = false;
            faceMessage.clear();
            backMessage.clear();
        }
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void pageReadyForWebView(final String id) {
        if (id.equals("0")) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    isBackReady = true;
                    for (String message : faceMessage) {
                        mWebView.loadUrl(generateJSOnMessageFunStr(id, message));
                    }
                }
            });
        } else {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    isFaceReady = true;
                    for (String message : backMessage) {
                        mFaceView.loadUrl(generateJSOnMessageFunStr(id, message));
                    }
                }
            });
        }
    }

    private String generateJSOnMessageFunStr(String id, String message) {
        String finalMsg = Uri.encode(message.replaceAll("\"", "\\\""));
        return "javascript: yspUser.onMessage(" + id + ", " + finalMsg + ")";
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public void refresh(final String model) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mJavascriptInterfaceModelInteractionListener.onRefresh(model);
            }
        });
    }

    @org.xwalk.core.JavascriptInterface
    @JavascriptInterface
    public String getUserInfo() {
        return mWebView.getContext().getSharedPreferences("ysp_rongCloud", Context.MODE_PRIVATE).getString("user_info_for_webview", "");
    }

    public String getPcUrl() {
        return mPcUrl;
    }

    public void setFaceWebView(FaceWebView faceView) {
        this.mFaceView = faceView;
    }

    public void setSupport2WebView(boolean support2WebView) {
        this.isSupport2WebView = support2WebView;
    }

    public interface OnJavascriptInterfaceModelInteractionListener {
        void onLoadAdapter();

        void onRefresh(String refreshModel);

        void onBack();

        void showLoading(String message);

        void hideLoading();

        void closeWindow();

        /**
         * 适配想开启新的WebView加载该url
         * 执行在子线程
         */
        void openWindow(String url);

        /**
         * 获取当前tab最后一次单点登录成功的时间戳
         */
        long getLastSSOTimeStamp();

        /**
         * 单点登录成功之后再次更新当前tab单点登录的时间戳
         */
        void updateSSOTimeStamp(long timeStamp);

        /**
         * 适配页面打开文档文件
         *
         * @param data 下载参数
         */
        void yspOpenDocFile(String data);

        void nativeEvent(NativeEventModel nativeEventModel);

        AutoLoginModel getAutoLoginConfig(String url);

        String getMenu();

        String getAppVersion();
    }
}
